package eerbaar.shared.persist.internal.lib;

import java.util.ArrayList;
import java.util.List;

import eerbaar.area.AreaConstants;
import eerbaar.area.AreaFactory;
import eerbaar.area.IArea;
import eerbaar.elements.ElementConstants;
import eerbaar.elements.IElement;
import eerbaar.shared.exceptions.GameException;
import eerbaar.shared.exceptions.GameRuntimeException;
import eerbaar.shared.persist.IPersistService;
import eerbaar.shared.persist.IPersister;
import eerbaar.shared.persist.ISaver;
import eerbaar.shared.service.ServiceFactory;
import eerbaar.shared.tree.IAttributes;
import eerbaar.shared.tree.INode;
import eerbaar.shared.tree.NodeCmdFactory;

public class AreaPersister implements IPersister<IArea> {

    static final String NAME = "area";

    private IArea target;

    public AreaPersister() {
        //
    }

    public AreaPersister(IArea wrapper) {
        this.target = wrapper;
    }

    public AreaPersister(INode node) throws GameRuntimeException {
        load(node);
    }

    @Override
    public Class<IArea> getRegistertedInterface() {
        return IArea.class;
    }

    @Override
    public ElementPersister[] getSavableChildren() {

        List<ElementPersister> result = new ArrayList<ElementPersister>();

        IElement[] elements = this.target.getElements();
        for (IElement e : elements) {
            ElementPersister p = new ElementPersister(e);
            result.add(p);
        }

        return result.toArray(new ElementPersister[] {});
    }

    @Override
    public String getSavableName() {
        return NAME;
    }

    @Override
    public IArea getTarget() {
        return this.target;
    }

    @Override
    public boolean isAssignableFrom(ISaver<?> savable) {
        return false;
    }

    @Override
    public IArea load(INode node) {
        assert (node != null);

        IAttributes attributes = node.getAttributes();
        int width = attributes.get(Integer.class, AreaConstants.WIDTH);
        int height = attributes.get(Integer.class, AreaConstants.HEIGHT);
        IArea result = AreaFactory.createArea(width, height);

        IPersistService service = ServiceFactory
                .getService(IPersistService.class);

        List<INode> list = NodeCmdFactory.findChildren(node,
                ElementConstants.ELEMENT_NAME);
        for (INode n : list) {
            try {
                IElement obj = service.load(IElement.class, n);
                result.addElement(obj);
            } catch (GameException e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    @Override
    public void saveAttributes(INode node) {

        IAttributes attributes = node.getAttributes();
        attributes.set(String.class, "name", NAME);
        attributes.set(Integer.class, AreaConstants.HEIGHT,
                this.target.getHeight());
        attributes.set(Integer.class, AreaConstants.WIDTH,
                this.target.getWidth());
    }

    @Override
    public void setTarget(IArea obj) {
        this.target = obj;
    }

}
